<?php

class FbFacade {
	const APP_ID = FB_APP_ID;
	const SECRET = FB_SECRET;
	const URL = BASE_URL;
	const USE_COOKIE = TRUE;
	const THROW_EXCEPTION = TRUE;
	const DISABLE_SSL_CHECK = FALSE;
	const DECODE_JSON = TRUE;
	const ALLOW_FILE_UPLOADS = FALSE;
	const CURL_TIMEOUT = 1000;
	const CURL_OPT_CONNECTTIMEOUT = 1000;
	const CA_CERT_PATH = CURL_CA_CERT_PATH;

	public static function factory($model, stdClass $obj = NULL) {
		$class_name = 'Facebook' . ucfirst(strtolower($model));
		if (!class_exists($class_name)) {
			throw new Exception($class_name . " does not exist.");
		}

		$output = new $class_name;
		if (!is_null($obj)) {
			foreach (get_object_vars($obj) as $key => $value) {
				$key = strtolower(rtrim($key, 's'));
				$method_name = (!is_array($value->data) || is_array($value) ? 'set_' : 'add_') . $key;
				if (is_array($value->data) || is_array($value)) {
					foreach ($value->data as $v) {
						if (!call_user_func(array($output, $method_name), self::factory($key, $v))) {
							throw new Exception('The method ' . $method_name . ' is not defined in the class ' . get_class($output));
						}
					}
				} elseif (is_object($value)) {
					if (!call_user_func(array($output, $method_name), self::factory($key, $value))) {
						throw new Exception('The method ' . $method_name . ' is not defined in the class ' . get_class($output));
					}
				} else {
					if (!call_user_func(array($output, $method_name), $value)) {
						throw new Exception('The method ' . $method_name . ' is not defined in the class ' . get_class($output));
					}
				}
			}
		}
		return $output;
	}

	public static function post_album(FacebookAlbum $album, $token) {
		$lib = FB::get_instance();
		$album_id = $album->get_id();
		if (is_null($album_id)) {
			$album_id = $lib->postAlbum(
					self::APP_ID,
					$token,
					array(
						'name' => $album->get_name(),
						'message' => $album->get_message()->get_message(),
				))->id;
			$album->set_id($album_id);
		}
		$rst = self::factory('result');
		$ids = '';
		$photos = $album->get_photos();
		if (!is_null($photos)) {
			foreach ($album->get_photos() as $photo) {
				$args['source'] = '@' . $photo->get_path();
				$args['message'] = $photo->get_message();
				$args['position'] = $photo->get_position();
				$rsp = $lib->postPhoto($album->get_id(), $token, $args);
				if (isset($rsp->error)) {
					$rst->error(TRUE);
					$rst->set($rsp->error->message);
					break;
				}
				$ids .= $rsp->id . ' ';
			}
		}
		if (empty($ids)) {
			$rst->error(TRUE);
			$msg = $rst->get();
			if (empty($msg)) {
				$rst->set('No photos were uploaded');
			}
		} else {
			$rst->set($ids);
		}
		return $rst;
	}

	public static function get_albums($with_photos = FALSE) {
		$albums = array();
		$lib = FB::get_instance();
		$rsp = $lib->getAlbums(FbFacade::APP_ID)->data;
		if (!empty($rsp)) {
			foreach ($rsp as $a) {
				$album = self::factory('album', $a);
				if ($with_photos) {
					$album->load_photos();
				}
				$albums[$album->get_id()] = $album;
			}
		}

		return $albums;
	}

	public static function post_feed(FacebookFeed $feed, $access_token) {

		$lib = FB::get_instance();
		$params['message'] = $feed->get_message();
		$params['link'] = $feed->get_link();
		$params['name'] = $feed->get_name();
		$params['description'] = $feed->get_description();
		$params['picture'] = $feed->get_image();
		$rst = self::factory('result');
		$rsp = $lib->postFeed($feed->get_id(), $access_token, $params);
		if (!isset($rsp->error)) {
			$rst->set($rsp->id);
		} else {
			$rst->error(TRUE);
			$rst->set($rsp->error->message);
		}
		return $rst;
	}

	public static function app_account() {
		$rst = self::accounts();
		if (!$rst->error()) {
			foreach ($rst->get() as $account) {
				if ($account->get_id() === FbFacade::APP_ID) {
					$rst->set($account);
					return $rst;
				}
			}
		}
		return $rst;
	}

	public static function accounts($access_token = NULL) {
		$lib = FB::get_instance();
		$fb_accounts = $lib->get_accounts();
		$rst = self::factory('result');
		if (!isset($fb_accounts->error)) {
			$accounts = array();
			foreach ($fb_accounts->data as $a) {
				$account = self::factory('account', $a);
				$accounts[$account->get_id()] = $account;
			}
			$rst->set($accounts);
		} else {
			$rst->error(TRUE);
			$rst->set($fb_accounts->error->message);
		}

		return $rst;
	}

	public static function perms(array $scope) {
		$js_perms = '';
		echo '<fb:login-button perms="' . implode(',', $scope) . '"></fb:login-button>';
	}

	private static function getAuthorizeUrl($callback_url = "", $perms = array()) {
		// return 'https://graph.facebook.com/oauth/authorize?client_id='.self::APP_ID.'&redirect_uri='.$callback_url.'&scope='.implode(",",$perms);
		return 'https://www.facebook.com/dialog/oauth?client_id=' . FbFacade::APP_ID . '&redirect_uri=' . $callback_url . '&scope=' . implode(",", $perms);
	}

	public static function post_link(FacebookLink $link, $post_id, $access_token = NULL) {
		$lib = Fb::get_instance();
		if (is_null($access_token)) {
			$access_token = $lib->getAccessToken();
		}
		$params['description'] = $link->get_description();
		$params['message'] = $link->get_message();
		$params['link'] = $link->get_link();
		$params['name'] = $link->get_name();
		$params['caption'] = $link->get_caption();
		$params['icon'] = $link->get_icon();
		$params['picture'] = $link->get_picture();
		$rst = self::factory('result');
		$rsp = $lib->postLink($post_id, $access_token, $params);
		if (isset($rsp->error)) {
			$rst->error(TRUE);
			$rst->set($rsp->error->message);
		} else {
			$rst->set($rsp->data->id);
		}
		return $rst;
	}

	public static function post_comment(FacebookComment $comment, $post_id, $access_token = NULL) {
		$lib = Fb::get_instance();
		if (is_null($access_token)) {
			$access_token = $lib->getAccessToken();
		}
		$rst = self::factory('result');
		$rsp = $lib->postComment($post_id, $access_token, $comment->get_message());
		if (isset($rsp->error)) {
			$rst->error(TRUE);
			$rst->set($rsp->error->message);
		} else {
			$rst->set($rsp->data->id);
		}
		return $rst;
	}

	public static function get_album_cover_link($cover_id) {
		return Fb::get_instance()->get_album_cover_link($cover_id);
	}

	public static function require_login(array $perms = NULL) {
		$lib = FB::get_instance();
		return $lib->require_login();
	}

}